原始题目:剑指 Offer 57. 和为s的两个数字 (opens new window)

解题思路:

因为给定的数组是有序的,这里可以用双指针来解题。

通过 startstartendend 指针,初始时 startstart 指向第一个元素,endend 指向最后一个元素,两个元素不断向中间靠近。

靠近的过程中,判断两个指针指向的元素的和 sumsum 是否为目标值 targettarget

  • 如果 sum=targetsum = target,说明这两个数时符合要求的,返回 startstartendend 指向的元素;
  • 如果 sum>targetsum > target,说明 endend 指向的数字太大,需要减小,endend 自减;
  • 如果 sum<targetsum < target,说明 startstart 指向的数字太小,需要增大,startstart 自增。

代码:

public int[] twoSum(int[] nums, int target) {
    if (nums == null || nums.length < 2) {
        return new int[0];
    }
    int start = 0;
    int end = nums.length - 1;
    while (start < end) {
        if (nums[start] + nums[end] == target) {
            return new int[]{nums[start], nums[end]};
        } else if (nums[start] + nums[end] > target) {
            end--;
        } else {
            start++;
        }
    }
    return new int[0];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

复杂度分析

  • 时间复杂度O(N)O(N):最差情况下,需要遍历所有的元素。
  • 空间复杂度O(1)O(1):辅助变量占用常数大小的额外空间。
上次更新: 2023/10/15